/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tetris_invader.personagens;

import java.awt.Graphics2D;
import java.awt.Image;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.Serializable;
import tetris_invader.itens.Item;
import tetris_invader.util.Fase;
import tetris_invader.util.Pair;

public class Nave extends Animacao implements Serializable, KeyListener {

    private float energia;
    /**
     * Nao é um ponto de fato. Apenas é um objeto da classe <i>Point</i> por conter
     * dois campos de posicao, facilmente manipulaveis.<br>
     * Controla a aceleracao do objeto na tela.
     */
    private Pair aceleracao;
    /**
     * Nao é um ponto de fato. Apenas é um objeto da classe <i>Point</i> por conter
     * dois campos de posicao, facilmente manipulaveis.<br>
     * Controla a velocidade de deslocamento na tela do objeto. Aumenta enquanto
     * alguma tecla direcional estiver seno pressionada e diminui caso contrário.
     */
    private Pair velocidade;
    private Item itens;
    /**
     * quantidade maxima de tiros que podem ser lancados por vez
     */
    private int beam;
    /**
     * Quantidade de pontuacao adquirida
     */
    private int score;
    /**
     * Booleano para saber se alguma tecla do teclado estava sendo presionada ou nao.<br>
     * Botao de aceleracao
     */
    private boolean keypress[];
    private int teclado[];
    /**
     * direcao em que esta se dirigindo:<br>
     *   [0] = norte<br>
     *   [1] = sul<br>
     *   [2] = leste<br>
     *   [3] = oeste<br><br>
     * <i>true</i> se estava se dirigindo naquela direcao<br>
     * <i>false</i> caso contrario
     */
    private boolean direction[];

    /**
     * Construtor da classe Nave
     * @param f A fase
     * @param imagens matriz de imagens da nave
     * @param velocidade a velocidade da nave
     */
    public Nave(Fase f, Image imagens[], int fps) {
        super(f, imagens, fps);
        this.vida = 3;

        size = 40;
        point.x = f.getHeight() / 2;
        point.y = f.getWidth() * 2 / 3;

        velocidade = new Pair();
        aceleracao = new Pair();

        teclado = new int[256];
        keypress = new boolean[4];
        direction = new boolean[4];
    }

    public void setPosition(int x, int y) {
        point.x = x;
        point.y = y;
    }

    /**
     *
     * @param quant soma um numero quant de vida
     */
    public void addVida(int quant) {
        this.vida += quant;
    }

    /**
     * Metodo que faz o deslocamento da nave na tela.<br>
     * Ela verifica se alguma tecla esta pressionada. Se sim, ela armazena essa
     * tecla em um vetor booleano e faz o deslocamento da nave naquela direcao,
     * adicionando uma aceleracao constante `a velocidade do objeto.<br>
     * Caso o botao nao seja mais pressionado, ha um decrescimo na aceleracao,
     * ate que o objeto chegue a velocidade nula.
     */
    @Override
    public void deslocamento() {
        //TODO deslocamento gambiarrado

        if (teclado[KeyEvent.VK_LEFT & 0xff] != 0) {
            this.point.x -= 12;//teclado[KeyEvent.VK_LEFT & 0xff];
        }
        if (teclado[KeyEvent.VK_RIGHT & 0xff] != 0) {
            this.point.x += 12;//teclado[KeyEvent.VK_RIGHT & 0xff];
        }
        if (teclado[KeyEvent.VK_UP & 0xff] != 0) {
            this.point.y -= 12;//teclado[KeyEvent.VK_UP & 0xff];
        }
        if (teclado[KeyEvent.VK_DOWN & 0xff] != 0) {
            this.point.y += 12;//teclado[KeyEvent.VK_DOWN & 0xff];
        }

//        this.point.x += velocidade.getX();
//        this.point.y += velocidade.getY();
    }

    private void acelera() {

        if (teclado[KeyEvent.VK_LEFT & 0xff] != 0) {
            velocidade.setX(velocidade.getX() - teclado[KeyEvent.VK_LEFT & 0xff]);
        }


//        if (direction[0]) {
//            aceleracao.setY(-1);
//        } else if (direction[1]) {
//            aceleracao.setY(1);
//        } else {
//            desaceleraY();
//        }
//        if (direction[2]) {
//            aceleracao.setX(1);
//        } else if (direction[3]) {
//            aceleracao.setX(-1);
//        } else {
//            desaceleraX();
//        }
    }

    public void desacelera() {
        desaceleraX();
        desaceleraY();
    }

    public void desaceleraX() {
        int aux = velocidade.xGreatThen(0);
        if (aux > 0) {
            this.velocidade.subtract(new Pair(1, 0));
        } else if (aux < 0) {
            this.velocidade.subtract(new Pair(-1, 0));
        } else {
            this.velocidade.setX(0);
        }
    }

    public void desaceleraY() {
        int aux = velocidade.yGreatThen(0);
        if (aux > 0) {
            this.velocidade.subtract(new Pair(0, 1));
        } else if (aux < 0) {
            this.velocidade.subtract(new Pair(0, -1));
        } else {
            this.velocidade.setY(0);
        }
    }

    public boolean atira() {
        if (teclado[KeyEvent.VK_SPACE & 0xff] > 0) {
            if (addBeam()) {
                return true;
            }
        }
        return false;
    }

    public boolean special() {
        if (teclado[KeyEvent.VK_Z & 0xff] > 0 && energia >= 100) {
            energia = 0;
            return true;
        }
        return false;
    }

    public void bomba() {
        //Ler uma imagem de boma e utilizar a atracao magnetica
    }

    @Override
    public void desenha(Graphics2D graphic) {
        graphic.drawImage(imagens[0], point.x, point.y, f);
    }

    @Override
    public boolean perdeVida() {
        this.vida -= 1;
        if (this.vida == 0) {
            return true;
        }
        return false;
    }

    @Override
    public void setVelocidade(float velocidade) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void setEnergia(float energia) {
        this.energia = energia;
    }

    public float getEnergia() {
        return this.energia;
    }

    public void addEnergia(float energia) {
        this.energia += energia;
    }

    public boolean addBeam() {
        if (beam + 1 > 5) {
            return false;
        }
        beam++;
        return true;
    }

    public void subtractBeam() {
        if (beam >= 1) {
            beam--;
        }
    }

    public void setScore(int score) {
        this.score = score;
    }

    public int getScore() {
        return this.score;
    }

    public void keyTyped(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        
        if (teclado[e.getKeyCode() & 0xff] <= 10) {
            teclado[e.getKeyCode() & 0xff]++;
        }


        switch (e.getKeyCode()) {
            case KeyEvent.VK_UP:
                if (direction[1]) {
                    direction[1] = false;
                }
                direction[0] = true;
                keypress[0] = true;
                break;

            case KeyEvent.VK_DOWN:
                if (direction[0]) {
                    direction[0] = false;
                }
                direction[1] = true;
                keypress[1] = true;
                break;

            case KeyEvent.VK_RIGHT:
                if (direction[3]) {
                    direction[3] = false;
                }
                direction[2] = true;
                keypress[2] = true;
                break;

            case KeyEvent.VK_LEFT:
                if (direction[2]) {
                    direction[2] = false;
                }
                direction[3] = true;
                keypress[3] = true;
                break;

            case KeyEvent.VK_F1:
                energia = 100;
                break;

            case KeyEvent.VK_F2:
                //vida += 5;
                break;
            default:
        }
    }

    public void keyReleased(KeyEvent e) {
        if (teclado[e.getKeyCode() & 0xff] > 0)
            teclado[e.getKeyCode() & 0xff] = 0;//-teclado[e.getKeyCode() & 0xff];
      
        switch (e.getKeyCode()) {
            case KeyEvent.VK_UP:
                keypress[0] = false;
                break;

            case KeyEvent.VK_DOWN:
                keypress[1] = false;
                break;

            case KeyEvent.VK_RIGHT:
                keypress[2] = false;
                break;

            case KeyEvent.VK_LEFT:
                keypress[3] = false;
                break;
            default:
        }
//
//        int k = hasKeyPress();
//        if (k >= 0) {
//            for (int i = 0; i < direction.length; i++) {
//                if (i != k) {
//                    direction[i] = false;
//                }
//            }
//        }
    }

    private int hasKeyPress() {
        int i = 0;
        for (i = 0; i < keypress.length; i++) {
            if (keypress[i]) {
                return i;
            }
        }
        return -1;
    }
}
